/*
 * MessageQueue.c
 *
 *  Created on: Oct 24, 2012
 *      Author: lakshmana s
 */

#include<stdio.h>
#include<strings.h>
#include "mq_interface.h"

/**
 * structure to hold the information of the student request
 * for course clearance from advisor

typedef struct Message {
	int student_id;
	//char student_name[50];
	char *student_name;
	int course_id;
	//char course_name[80];
	char *course_name;
	int clarance;
}Msg_t;
 */
/**
 * structure to hold the messages in the queue fashion
 * implemented as a linked list
 */
typedef struct MessageQueue{
	Msg_t request;
	struct MessageQueue *prev;
	struct MessageQueue *next;
}Msg_Node_t;

//head pointer for Message queue
Msg_Node_t *head=NULL;
//msgCount for Message Queue
int msgCount=0;

const char *MESSAGE_FILE_NAME ="../Msg_File_Persist.txt";
// File for persisting messages


static Msg_t ret=NULL;



/**
 * adds a new message to the front of the queue
 */
int addMsg(Msg_Node_t *newMsg){
	Msg_Node_t *temp;

	if(newMsg==NULL){
		printf("newMsg is null, insert failed\n");
		return 0;
	}

	if(head==NULL){
		head=newMsg;
		msgCount++;
		return 1;
	}
	temp=head;
	while(temp->next!=NULL){
		temp=temp->next;
	}
	temp->next=newMsg;
	newMsg->prev=temp;
	msgCount++;
	return 1;
}

int compareMsgRequest(Msg_t req1,Msg_t req2){
	if(req1==NULL || req2==NULL){
		printf("compare failed, null message");
		return 0;
	}
	if( req1->student_id==req2->student_id &&
			req1->course_id==req2->course_id )
		return 1;
	else
		return 0;
}


/**
 * removes a message from the queue
 */
int removeMsg(Msg_Node_t *msg){
	Msg_Node_t *temp;
	if(msg==NULL){
		printf("remove failed, newMsg is null\n");
		return 0;
	}
	temp=head;
	if(temp!=NULL  && msgCount>0) {
		if(compareMsgRequest(msg->request,temp->request)==1){
			temp=temp->next;
			free(head);
			head=temp;
			msgCount--;
			return 1;
		}
		while(temp->next!=NULL){
			if(compareMsgRequest(msg->request,temp->request)==1){
				temp->prev->next=temp->next;
				temp->next->prev=temp->prev;
				free(temp);
				msgCount--;
				return 1;
			}
			temp=temp->next;
		}
		if(temp!=NULL){
			if(compareMsgRequest(msg->request,temp->request)==1){
				Msg_Node_t *rel=temp;
				temp=temp->prev;
				temp->next=NULL;
				free(rel);
				msgCount--;
				return 1;
			}
		}
	}
	printf("message not found\n");
	return 0;

}

/**
 * copies message from one structure var to another
 */
void copy_message(Msg_t msg1, Msg_t msg2){

	msg1->source=(char*)malloc(80);
    strcpy(msg1->source,msg2->source);

	msg1->student_id=msg2->student_id;

	msg1->student_name=(char*)malloc(80);
	strcpy(msg1->student_name,msg2->student_name);

	msg1->course_id=msg2->course_id;

	msg1->course_name=(char*)malloc(80);
	strcpy(msg1->course_name,msg2->course_name);

	msg1->clearance=msg2->clearance;

}


/**
 * this method fetch the first message of the type source
 */
Msg_t fetchMsg(char *source){
	Msg_Node_t *temp;
	ret=(Msg_t)malloc(sizeof(Message));

	if(source==NULL){
		printf("fetch failed, source is null\n");
		return 0;
	}
	printf("looking for messages \n");
	temp=head;
	if(temp!=NULL && msgCount>0){
		if(strcmp(temp->request->source,source)==0){
			copy_message(ret,temp->request);
			printf("Message found \n");
			printf("Source    : %s  \n"
					"Student ID: %d  Name :%s \n"
					"Course Id : %d  Name :%s \n"
					"clearance : %d \n",
			ret->source,ret->student_id,ret->student_name,ret->course_id,ret->course_name,ret->clearance);
			removeMsg(temp);
			return ret;
		}
		while(temp->next!=NULL){
			if(strcmp(temp->request->source,source)==0){
				copy_message(ret,temp->request);
				printf("Message found \n");
				printf("Source    : %s  \n"
						"Student ID: %d  Name :%s \n"
						"Course Id : %d  Name :%s \n"
						"clearance : %d \n",
				ret->source,ret->student_id,ret->student_name,ret->course_id,ret->course_name,ret->clearance);
				removeMsg(temp);
				return ret;
			}
			temp=temp->next;
		}
		if(temp!=NULL){
			if(strcmp(temp->request->source,source)==0){
				copy_message(ret,temp->request);
				printf("Message found \n");
				printf("Source    : %s  \n"
						"Student ID: %d  Name :%s \n"
						"Course Id : %d  Name :%s \n"
						"clearance : %d \n",
				ret->source,ret->student_id,ret->student_name,ret->course_id,ret->course_name,ret->clearance);
				removeMsg(temp);
				return ret;
			}
		}
	}
	printf("No Messages \n");
	return ret;
}



/**
 * displays all the messages in the queue
 */
void displayMsges(){
	Msg_Node_t *temp=head;
	if(temp==NULL){
		printf("Message queue is empty \n");
		return ;
	}
	while(temp!=NULL){
		printf("Source : %s \n",temp->request->source);
		printf("ID : %d \n",temp->request->student_id);
		printf("Student Name : %s \n",temp->request->student_name);
		printf("Course ID : %d \n",temp->request->course_id);
		printf("Course Name : %s \n",temp->request->course_name);
		printf("Clearance : %d \n",temp->request->clearance);
		temp=temp->next;
	}
}


void saveMsges(){
	 FILE *msgFile=NULL;
	if(msgFile ==NULL){
		msgFile=fopen(MESSAGE_FILE_NAME,"w");
	}

	if(msgFile!=NULL && msgCount>0 && head!=NULL){
		int i=0;
		Msg_Node_t *temp=head;
		fprintf(msgFile," %d \n",msgCount);

		for(i=0;i<msgCount && temp!=NULL ;i++,temp=temp->next){
			fprintf(msgFile," %s ",temp->request->source);
			fprintf(msgFile," %d ",temp->request->student_id);
			fprintf(msgFile," %s ",temp->request->student_name);
			fprintf(msgFile," %d ",temp->request->course_id);
			fprintf(msgFile," %s ",temp->request->course_name);
			fprintf(msgFile," %d ",temp->request->clearance);
			fprintf(msgFile," \n");

		}
	printf("Messages persisted\n");
	}
	else
		printf("No Messages persisted \n");
	fclose(msgFile);
}


/**
 * Restoring messages from file to linked list
 */
void restoreMsges(){
	int readMsgCount=0;
	FILE *msgFile=NULL;
	int student_id, course_id,clearance;
	char source[20],student_name[20],course_name[20];

	Msg_t msg =NULL;
	Msg_Node_t *msg_node =NULL;

	if(msgFile ==NULL){
			msgFile=fopen(MESSAGE_FILE_NAME,"r");
		}
	if(msgFile!=NULL){
		fscanf(msgFile,"%d",&readMsgCount);
		printf("No of messages in file : %d \n",readMsgCount);
		if(readMsgCount>0 ){
			int i=0;
			for(i=0;i<readMsgCount;i++){
				fscanf(msgFile,"%s %d %s %d %s %d\n",
						source,&student_id,student_name,&course_id,course_name,&clearance);
				//printf("%s %d %s %d %s %d %s %d\n",source,student_id,student_name,course_id,course_name,clearance);
				msg=(Msg_t) malloc(sizeof(Message));
				msg_node=(Msg_Node_t*) malloc(sizeof(Msg_Node_t));

				msg->source =(char*)malloc(strlen(source)+1);
				strcpy(msg->source,source);

				msg->student_id=student_id;
				msg->student_name=strdup(student_name);
				msg->course_id=course_id;
				msg->course_name=strdup(course_name);
				msg->clearance=clearance;

				msg_node->request=msg;
				msg_node->next=NULL;
				msg_node->prev=NULL;
				//printf("%s %d %s %d %s %d\n",
				//msg->source,msg->student_id,msg->student_name,msg->course_id,msg->course_name,msg->clearance);
				addMsg(msg_node);
			}
		printf("Messages restored successfully \n");
		}
	}
	else
		printf("Messages restore failed \n");
	fclose(msgFile);
}
